'''
同步城市实况天气信息
'''
from django.core.management.base import BaseCommand, CommandError
from weather.models import WeatherLive, CityNumber
from publicApi import settings
import requests
import time
from requests import RequestException, ConnectionError

FLASK_SERVER_HOST = getattr(settings, 'FLASK_SERVER_HOST', 'http://127.0.0.1:5000/')


class SyncRemoteData(object):

    mycount = 0
    next_url = None
    # previous_url = None
    # counts = 0

    def __init__(self, *args, **kwargs):
        # print("==>> args", *args, len(args))
        self.page, self.page_size, self.option, self.handCounts = args
    
    @property
    def initUrl(self):
        '''第一次请求的url'''
        return '%s%s?page=%s&page_size=%s' % (FLASK_SERVER_HOST, self.option, self.page, self.page_size)

    def getData(self, url):
        '''获取数据'''
        print('get ', url)
        response = requests.get(url)
        if response.status_code != 200:
            # logging
            return
        datas = response.json()
        # self.previous_url = datas.get('previous', None)
        self.next_url = datas.get('next', None)
        # self.counts = datas.get('counts', 0)

        return datas.get('results', [])

    def dataHandler(self, url):
        '''数据单次请求处理器：数据适配处理、数据写入数据库处理'''

        result = self.getData(url)
        for res in result:
            try:
                city_number = CityNumber.objects.get(city_number=int(res['city']))
            except Exception as e:
                # logging
                print('+===>> get city_number Exception!', e)
                continue
            wl = res.get('WS', None)
            pm25 = res.get('aqi_pm25', None)
            rain = res.get('rain', None)
            sk_time = res.get('time', None)
            new_obj = {
                'temp': res.get('temp', None),
                'temp_highest': res.get('temp_highest', None),
                'temp_lowest': res.get('temp_lowest', None),
                'temp_unit': res.get('temp_unit', None),
                'wd': res.get('WD', None),
                'wind_level': int(wl[0:-1]) if wl else None,
                'wind_speed': res.get('wse', '').replace('&lt;', ''),
                'rh': res.get('SD', None),
                'weather': res.get('weather', None),
                'pm25': float(pm25) if pm25 else None,
                'updated': sk_time if sk_time else None,
                'rain': float(rain) if rain else None,
                'limit': res.get('limitnumber', None),
                'city_number': city_number,
            }

            WeatherLive.objects.update_or_create(city_number=city_number, defaults=new_obj)
            # print("====>> %s success!" % res['city'])
        
        self.mycount = self.mycount + self.page_size

    def sync(self, url=''):
        '''递归：请求所有数据'''
        if self.mycount != 0:
            if self.next_url is None or self.mycount > self.handCounts:
                # 非首次 self.next_url is None 就退出
                print("===>> self.next_url is %s ! " % self.next_url)
                return
            try:
                self.dataHandler(url)
                self.sync(self.next_url)
            except ConnectionError as e:  # 网络不好，连接超时 | ps:我写时是在内网环境下，没有连接超时的问题
                print("===>> ConnectionErrore", e)
                self.sync(url)
            return
        
        self.dataHandler(self.initUrl)
        self.sync(self.next_url)


class Command(BaseCommand):
    '''
    实现自定义命令 sync_weather
    '''
    can_import_settings = True
    help = 'Implement custom naming: "sync_weather".'

    def add_arguments(self, parser):
        parser.add_argument(
            '--page',
            action='store',
            dest='page',
            default=1,
            type=int,
        )
        parser.add_argument(
            '--size',
            action='store',
            dest='page_size',
            default=50,
            type=int,
        )
        parser.add_argument(
            '--count',
            action='store',
            dest='hand_counts',
            default=200,
            type=int,
        )

    def handle(self, *args, **options):
        page = options['page']
        page_size = options['page_size']
        hand_counts = options['hand_counts']
        
        sync_remote = SyncRemoteData(page, page_size, 'weather', hand_counts)
        sync_remote.sync()

        self.stdout.write(self.style.SUCCESS('%s part of %s sync Successfully!') % (page, WeatherLive.__name__))